package csel.model.entity;

import java.util.Map;

import org.apache.log4j.Logger;

import csel.model.*;
import csel.model.items.EquippableItem;
import csel.model.items.UseableItem;

public abstract class Vehicle extends Entity
{
	private static final long serialVersionUID = 5L;

	private static final Logger logger = Logger.getLogger("csel.model");
	
	private VehicleStatHolder vehicleStatHolder;
	//no entity inside vehicle as of yet
	private Entity entityInsideMe = null;
	
	Vehicle(String typeId)
	{
		super(typeId);
		vehicleStatHolder = new VehicleStatHolder();
		// TODO
	}
	@Override
	public boolean canEnter(MobileObject obj, BlockNotifier notifier)
	{
		if (notifier != null)
			notifier.blockedBy(this);
		
		return false;
	}
	
	/**
	 * Get in the Vehicle.
	 */
	public boolean enter(Entity e)
	{
		if (!canHold(e))
			return false;
		
		entityInsideMe = e;
		e.move((Tile)null);
		
		return true;
	}

	/**
	 * Get out of the vehicle.
	 */
	public void leave(Entity e)
	{
		Tile target;
		
		target = this.getTile().getNeighbor(Direction.NORTH);
		
		if (!target.canEnter(e, null))
			throw new NoCanDoException("Can't egress, destination tile blocked.");

		logger.info(String.format("%s leaving Vehicle, dropping at %s.", e, target));
		
		//TODO consider walls and stuff?
		e.move(target);
		entityInsideMe = null;
	}
	
	public boolean canLeave(Entity e)
	{
		return (this.getTile().getNeighbor(Direction.NORTH).canEnter(e, null));
	}

	public boolean canHold(Entity e)
	{
		return (entityInsideMe == null);
	}
	
	public int getVehicleStat(VehicleStats v)
	{
		return vehicleStatHolder.getStat(v);
	}

	public Map<VehicleStats, Integer> getVehicleStats()
	{
		// TODO
		return vehicleStatHolder.getStats();
	}
	
	public void setVehicleStat(VehicleStats vs, int value)
	{
		vehicleStatHolder.setStat(vs, value);
	}

	public int getSpeed()
	{
		return getVehicleStat(VehicleStats.Speed);
	}

	@Override
	public boolean isImpassable()
	{
		return true;
	}
	
	public boolean touch(EquippableItem ei)
	{
		//default does nothing just runs over an item
		return false;
	}
	
	public boolean touch(UseableItem ui)
	{
		//default does nothing just runs over an item
		return false;
	}
	
	public void die()
	{
		//TODO think of a better method also resistance may affect it
		leave(entityInsideMe);
		setVehicleStat(VehicleStats.Damage, vehicleStatHolder.getStat(VehicleStats.MaxLife));
	}
	
	public void levelUp()
	{
		//Doesn't do anything. Vehicle should not level up.
	}
	
	@Override
	public void damage(DamageTypes dT, int dam)
	{
		double resistanceModifier = (vehicleStatHolder.getResistance(dT)/100.0);
		int damage = (int)(dam * resistanceModifier);
		vehicleStatHolder.setStat(VehicleStats.Damage, vehicleStatHolder.getStat(VehicleStats.Damage)+damage);
	}
	
	public boolean can(MoveAbilities ability)
	{
		return super.can(ability);
	}
}
